<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title> 原型和原型链 的简单简介 </title>
</head>
<body>
    
</body>
</html>
<script>
    /*原型和原型链 是js初学者的噩梦 
      虽然工作过程中用不到 但理解它 对于我们写代码 看源码有很大的提升的！*/


    //原型概念 
    //在js中万物皆对象
    //每一个js"对象"创建的时候 就会与之关联另一个对象 这个对象就是我们所说的原型 每一个对象都会从原型中 继承属性 

    //prototype 
    //在js中 每一个函数都有一个prototype属性 该属性指向函数的原型对象 
    //当用该函数构造出 一些对象之后 这些对象也继承了原型对象上的属性  看代码
    function Person(){}
    Person.prototype.name = "protoName"
    var person1 = new Person()
    console.log(Person1.name)   //protName
    /*注意person1 由于本身上没有name这个属性 所以他会去构造函数Person找  而person函数本身也没有name属性 所以会去Person.prototype上找
      也就是去Person的原型上面找 这就是基本的原型链了 */    
    //1.jpg 是执行步骤昂   


    //proto
    //每个对象都有一个_proto_属性 它指向该对象的原型 就是说   
    function Person(){}    
    var person1 = new Person()
    console.log(person1._proto_ === Person.prototype) // true  
    //2.jpg 是执行的步骤  


    //constructor
    //每个原型 都有一个constructor (就是说constructor是存在prototype上面的属性) 指向关联的构造函数  代码如下
    function Person(){}
    var Person1 = new Person() 
    console.log(Person.prototype.constructor === Person)                //true   
    console.log(Person.prototype.constructor === Person1.constructor)   //true
    //person1本身没有constructor属性 所以UI沿着 继续向原型链顶端找 去它的构造函数person函数上找 而构造函数的原型上面有constructor属性 
    //就是说 person1没有constructor属性 查找Person的constructor属性 Person没有constructor属性 查找Person.prototype的constructor属性 
    //3.jpg 所示了  



    //原型的原型 
    //原型本质也是一个对象 那么对象可以通过new Object构建出来  
    //就是说 原型的_proto_属性指向原型的原型 也就是Object.prototype 
    function Perrson(){}
    var person1 = new Perrson();
    console.log(Person.__proto__ === Function.prototype)         // true
    console.log(Person.prototype.__proto__ === Object.prototype) // true
    //4.jpg 所示

/*
    综上所述 摘自《javascript高级程序设计》
    回顾构造函数 原型和实例的关系 每一个构造函数都有一个原型对象 原型对象都包含一个指向构造函数的指针 
而实例都包含一个指向对象的内部指针     
    那么假如我们让原型对象等于 另一个类型的实例 结果？此时原型对象将包含一个指向另一个原型的指针 相应
的 另一个原型中也包含着一个指向另一个构造函数的指针 假如另一个原型又是另一个类型的实例 那么上述关系依
然成立 如此层层递进  构成了实例于原型的链条 这就是所谓的原型链的基本概念啊     
    是不是 一脸懵逼 哈哈哈
    
    我的理解
    就是说 假如函数a的原型是函数b的实例对象 而函数b的原型是函数c的实例对象 函数c的原型是函数d的实例对象
那么a b c d 就会构成一个原型链  
    此时如果函数a的实例对象需要去找一个属性x 在函数a找不到的时候 就去函数a的原型上找 再找不到就去去函数b
的原型上面找  就是说沿着原型链 一层一层的找         
    嗯呐 就是这样 
*/
  
 
//构造原型关系的方法 
    //确定原型链中 出现过的构造函数  结果会返回 true  
    //instanceof
    function Person(){}
    var person1 = new Person()
    console.log(person1 instanceof Person)    //true
    console.log(person1 instanceof Object)    //true
    //因为所有对象的原型都是 Object.prototype 所以也会在原型链上  

    //isPrototypeOf
    //用法和instanceof差不多  
    function Person(){}
    var person1 = new Person()
    console.log(Person.prototype.isPrototypeOf(person1)) // true
    console.log(Object.prototype.isPrototypeOf(person1)) // true

    //...oh



// 摘自 掘金 
// 创建一个函数就会为其创建一个prototype属性，指向这个函数的原型对象，原型对象会自动获得constructor属性，指向prototype属性所在函数。
// 当一个对象调用某个方法或者属性的时候，先在自身查找，如果找到就调用，如果没有就顺着__proto__到原型对象中查找，如果还没有就继续去原型的原型中查
// ，一直到null，这样形成一条链叫做原型链。如果还没有找到就返回undefined。



















    













    













</script>